package org.hilo.boot.core;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.persistence.Id;
import javax.persistence.Table;

import org.springframework.util.ReflectionUtils;


/**
 * <p>
 * 实体类反射表辅助类
 * </p>
 *
 * @author hubin sjy
 * @Date 2016-09-09
 */
public class TableInfoHelper {

    /**
     * 缓存反射类表信息
     */
    private static final Map<String, TableInfo> tableInfoCache = new ConcurrentHashMap<>();

    /**
     * <p>
     * 获取实体映射表信息
     * <p>
     *
     * @param clazz 反射实体类
     * @return
     */
    public static TableInfo getTableInfo(Class<?> clazz) {
        return tableInfoCache.get(clazz.getName());
    }

    /**
     * <p>
     * 实体类反射获取表信息【初始化】
     * <p>
     *
     * @param clazz 反射实体类
     * @return
     */
    public synchronized static TableInfo initTableInfo(Class<?> clazz) {
        TableInfo ti = tableInfoCache.get(clazz.getName());
        if (ti != null) {
            return ti;
        }
        
        if(clazz.getAnnotation(Table.class)==null) {
            return null;
        }
        
        
        TableInfo tableInfo = new TableInfo();
        List<Field> list = getAllFields(clazz);
        
        for (Field field : list) {
            Id gen = field.getAnnotation(Id.class);
            if (gen != null) {
                tableInfo.setKeyProperty(field.getName());
                break;
            }
        }
        
        /*
         * 注入
         */
        tableInfoCache.put(clazz.getName(), tableInfo);
        return tableInfo;
    }

    /**
     * <p>
     * 判断主键注解是否存在
     * </p>
     *
     * @param list 字段列表
     * @return
     */
    public static boolean existTableId(List<Field> list) {
        boolean exist = false;
        for (Field field : list) {
            Id tableId = field.getAnnotation(Id.class);
            if (tableId != null) {
                exist = true;
                break;
            }
        }
        return exist;
    }

    
    /**
     * 获取该类的所有属性列表
     *
     * @param clazz 反射类
     * @return
     */
    private static List<Field> getAllFields(Class<?> clazz) {
        final List<Field> fieldList = new ArrayList<>();
        ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
            @Override
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                fieldList.add(field);
            }
        });
        return fieldList;
    }

}
